From: Jonas Dreßler Date: Fri, 9 Dec 2022 22:43:23 +0000 (+0100) Subject: appDisplay: Switch page when hovering the next-page indicator during DND X-Git-Tag: archive/raspbian/50.5-1+rpi1~1^2~405^2^2~187 X-Git-Url: https://dgit.raspbian.org/%22http://www.example.com/cgi/%22/%22http:/www.example.com/cgi/%22?a=commitdiff_plain;h=560565d8281f9043df92ed48d6dda0753149e025;p=gnome-shell.git appDisplay: Switch page when hovering the next-page indicator during DND In addition to the "overshoot/bumping into monitor edge" behavior we already have, we also want to switch pages when simply hovering above the prev/next page indicators. This page switch shouldn't happen immediately though, it needs to be kicked off using a timeout instead. The reason for that is that the next/prev page indicators are large areas, and simply dragging there isn't enough of a gesture to really interpret as "the user wants to switch pages". After this page switch has been toggled once, it can be repeated using the same "repeat" timeout we introduced with the last commit. Part-of: --- diff --git a/js/ui/appDisplay.js b/js/ui/appDisplay.js index 8c75f0473..bb2cb5922 100644 --- a/js/ui/appDisplay.js +++ b/js/ui/appDisplay.js @@ -43,7 +43,9 @@ const PAGE_PREVIEW_ANIMATION_TIME = 150; const PAGE_INDICATOR_FADE_TIME = 200; const PAGE_PREVIEW_RATIO = 0.20; +const DRAG_PAGE_SWITCH_INITIAL_TIMEOUT = 1000; const DRAG_PAGE_SWITCH_IMMEDIATELY_THRESHOLD_PX = 20; + const DRAG_PAGE_SWITCH_REPEAT_TIMEOUT = 1000; const DELAYED_MOVE_TIMEOUT = 200; @@ -838,7 +840,12 @@ var BaseAppView = GObject.registerClass({ this._delayedMoveData = null; } - _resetDragPageSwitchRepeat() { + _resetDragPageSwitch() { + if (this._dragPageSwitchInitialTimeoutId) { + GLib.source_remove(this._dragPageSwitchInitialTimeoutId); + delete this._dragPageSwitchInitialTimeoutId; + } + if (this._dragPageSwitchRepeatTimeoutId) { GLib.source_remove(this._dragPageSwitchRepeatTimeoutId); delete this._dragPageSwitchRepeatTimeoutId; @@ -848,8 +855,7 @@ var BaseAppView = GObject.registerClass({ } _setupDragPageSwitchRepeat(direction) { - if (this._dragPageSwitchRepeatTimeoutId) - GLib.source_remove(this._dragPageSwitchRepeatTimeoutId); + this._resetDragPageSwitch(); this._dragPageSwitchRepeatTimeoutId = GLib.timeout_add(GLib.PRIORITY_DEFAULT, DRAG_PAGE_SWITCH_REPEAT_TIMEOUT, () => { @@ -864,7 +870,7 @@ var BaseAppView = GObject.registerClass({ _dragMaybeSwitchPageImmediately(dragEvent) { // Already animating if (this._adjustment.get_transition('value') !== null) - return; + return false; const [gridX, gridY] = this.get_transformed_position(); const [gridWidth, gridHeight] = this.get_transformed_size(); @@ -887,14 +893,14 @@ var BaseAppView = GObject.registerClass({ // pages. if (this._lastOvershootCoord >= 0 && moveDelta > DRAG_PAGE_SWITCH_IMMEDIATELY_THRESHOLD_PX) - this._resetDragPageSwitchRepeat(); + this._resetDragPageSwitch(); - return; + return false; } // Still in the area of the previous overshoot if (this._lastOvershootCoord >= 0) - return; + return false; let direction = dragCoord <= gridStart ? -1 : 1; if (this.get_text_direction() === Clutter.TextDirection.RTL) @@ -904,6 +910,26 @@ var BaseAppView = GObject.registerClass({ this._setupDragPageSwitchRepeat(direction); this._lastOvershootCoord = dragCoord; + + return true; + } + + _maybeSetupDragPageSwitchInitialTimeout(dragEvent) { + if (this._dragPageSwitchInitialTimeoutId || this._dragPageSwitchRepeatTimeoutId) + return; + + const {targetActor} = dragEvent; + + this._dragPageSwitchInitialTimeoutId = + GLib.timeout_add(GLib.PRIORITY_DEFAULT, DRAG_PAGE_SWITCH_INITIAL_TIMEOUT, () => { + const direction = targetActor === this._prevPageIndicator ? -1 : 1; + + this.goToPage(this._grid.currentPage + direction); + this._setupDragPageSwitchRepeat(direction); + + delete this._dragPageSwitchInitialTimeoutId; + return GLib.SOURCE_REMOVE; + }); } _onDragBegin() { @@ -923,8 +949,23 @@ var BaseAppView = GObject.registerClass({ const appIcon = dragEvent.source; - if (appIcon instanceof AppViewItem) - this._dragMaybeSwitchPageImmediately(dragEvent); + if (appIcon instanceof AppViewItem) { + // Two ways of switching pages during DND: + // 1) When "bumping" the cursor against the monitor edge, we switch + // page immediately. + // 2) When hovering over the next-page indicator for a certain time, + // we also switch page. + + if (!this._dragMaybeSwitchPageImmediately(dragEvent)) { + const {targetActor} = dragEvent; + + if (targetActor === this._prevPageIndicator || + targetActor === this._nextPageIndicator) + this._maybeSetupDragPageSwitchInitialTimeout(dragEvent); + else + this._resetDragPageSwitch(); + } + } this._maybeMoveItem(dragEvent); @@ -944,7 +985,7 @@ var BaseAppView = GObject.registerClass({ this._dragMonitor = null; } - this._resetDragPageSwitchRepeat(); + this._resetDragPageSwitch(); this._appGridLayout.hidePageIndicators(); this._swipeTracker.enabled = true;